In [ ]:
import matplotlib.pyplot as plt
import geopandas as gpd
In [ ]:
import warnings
# warnings.filterwarnings('ignore')
warnings.filterwarnings('ignore', category=DeprecationWarning)
In [ ]:
!pip install r5py
Requirement already satisfied: r5py in /usr/local/lib/python3.10/dist-packages (0.1.1)
Requirement already satisfied: ConfigArgParse in /usr/local/lib/python3.10/dist-packages (from r5py) (1.7)
Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from r5py) (3.14.0)
Requirement already satisfied: fiona in /usr/local/lib/python3.10/dist-packages (from r5py) (1.9.6)
Requirement already satisfied: geopandas in /usr/local/lib/python3.10/dist-packages (from r5py) (0.13.2)
Requirement already satisfied: importlib-resources in /usr/local/lib/python3.10/dist-packages (from r5py) (6.4.0)
Requirement already satisfied: joblib in /usr/local/lib/python3.10/dist-packages (from r5py) (1.4.2)
Requirement already satisfied: jpype1 in /usr/local/lib/python3.10/dist-packages (from r5py) (1.5.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from r5py) (1.25.2)
Requirement already satisfied: pandas>=2.1.0 in /usr/local/lib/python3.10/dist-packages (from r5py) (2.2.2)
Requirement already satisfied: psutil in /usr/local/lib/python3.10/dist-packages (from r5py) (5.9.5)
Requirement already satisfied: pyproj in /usr/local/lib/python3.10/dist-packages (from r5py) (3.6.1)
Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from r5py) (2.31.0)
Requirement already satisfied: shapely>=2.0 in /usr/local/lib/python3.10/dist-packages (from r5py) (2.0.4)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2023.4)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2024.1)
Requirement already satisfied: attrs>=19.2.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (23.2.0)
Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (2024.6.2)
Requirement already satisfied: click~=8.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (8.1.7)
Requirement already satisfied: click-plugins>=1.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (1.1.1)
Requirement already satisfied: cligj>=0.5 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (0.7.2)
Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (1.16.0)
Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from geopandas->r5py) (24.1)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (3.7)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (2.0.7)
In [ ]:
!pip install pyrosm
Requirement already satisfied: pyrosm in /usr/local/lib/python3.10/dist-packages (0.6.2)
Requirement already satisfied: python-rapidjson in /usr/local/lib/python3.10/dist-packages (from pyrosm) (1.17)
Requirement already satisfied: setuptools>=18.0 in /usr/local/lib/python3.10/dist-packages (from pyrosm) (67.7.2)
Requirement already satisfied: geopandas>=0.12.0 in /usr/local/lib/python3.10/dist-packages (from pyrosm) (0.13.2)
Requirement already satisfied: shapely>=2.0.1 in /usr/local/lib/python3.10/dist-packages (from pyrosm) (2.0.4)
Requirement already satisfied: cykhash in /usr/local/lib/python3.10/dist-packages (from pyrosm) (2.0.1)
Requirement already satisfied: pyrobuf in /usr/local/lib/python3.10/dist-packages (from pyrosm) (0.9.3)
Requirement already satisfied: fiona>=1.8.19 in /usr/local/lib/python3.10/dist-packages (from geopandas>=0.12.0->pyrosm) (1.9.6)
Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from geopandas>=0.12.0->pyrosm) (24.1)
Requirement already satisfied: pandas>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from geopandas>=0.12.0->pyrosm) (2.2.2)
Requirement already satisfied: pyproj>=3.0.1 in /usr/local/lib/python3.10/dist-packages (from geopandas>=0.12.0->pyrosm) (3.6.1)
Requirement already satisfied: numpy<3,>=1.14 in /usr/local/lib/python3.10/dist-packages (from shapely>=2.0.1->pyrosm) (1.25.2)
Requirement already satisfied: jinja2>=2.8 in /usr/local/lib/python3.10/dist-packages (from pyrobuf->pyrosm) (3.1.4)
Requirement already satisfied: cython>=0.23 in /usr/local/lib/python3.10/dist-packages (from pyrobuf->pyrosm) (3.0.10)
Requirement already satisfied: attrs>=19.2.0 in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.19->geopandas>=0.12.0->pyrosm) (23.2.0)
Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.19->geopandas>=0.12.0->pyrosm) (2024.6.2)
Requirement already satisfied: click~=8.0 in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.19->geopandas>=0.12.0->pyrosm) (8.1.7)
Requirement already satisfied: click-plugins>=1.0 in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.19->geopandas>=0.12.0->pyrosm) (1.1.1)
Requirement already satisfied: cligj>=0.5 in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.19->geopandas>=0.12.0->pyrosm) (0.7.2)
Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.19->geopandas>=0.12.0->pyrosm) (1.16.0)
Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2>=2.8->pyrobuf->pyrosm) (2.1.5)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.1.0->geopandas>=0.12.0->pyrosm) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.1.0->geopandas>=0.12.0->pyrosm) (2023.4)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.1.0->geopandas>=0.12.0->pyrosm) (2024.1)
In [ ]:
from pyrosm import OSM, get_data
In [ ]:
warsaw_osm = OSM(get_data("warsaw"))
In [ ]:
from r5py import TransportNetwork

# Set the file path to the OSM data
warsaw_osm = '/content/drive/MyDrive/Projekt zaliczeniowy/Warsaw.osm.pbf'

# Initialize the TransportNetwork with OSM and GTFS data
transport_network = TransportNetwork(
    warsaw_osm,  # OSM data file path as a string
    [
        '/content/drive/MyDrive/Projekt zaliczeniowy/warsaw.zip'  # GTFS file(s)
    ]
)
In [ ]:
!apt-get -qq install -y libspatialindex-dev
!pip install -q -U osmnx
!pip install folium matplotlib mapclassify
Requirement already satisfied: folium in /usr/local/lib/python3.10/dist-packages (0.14.0)
Requirement already satisfied: matplotlib in /usr/local/lib/python3.10/dist-packages (3.7.1)
Requirement already satisfied: mapclassify in /usr/local/lib/python3.10/dist-packages (2.6.1)
Requirement already satisfied: branca>=0.6.0 in /usr/local/lib/python3.10/dist-packages (from folium) (0.7.2)
Requirement already satisfied: jinja2>=2.9 in /usr/local/lib/python3.10/dist-packages (from folium) (3.1.4)
Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from folium) (1.25.2)
Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from folium) (2.31.0)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib) (1.2.1)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib) (4.53.0)
Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib) (1.4.5)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib) (24.1)
Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib) (9.4.0)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib) (3.1.2)
Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/dist-packages (from matplotlib) (2.8.2)
Requirement already satisfied: networkx>=2.7 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (3.3)
Requirement already satisfied: pandas!=1.5.0,>=1.4 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (2.2.2)
Requirement already satisfied: scikit-learn>=1.0 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (1.2.2)
Requirement already satisfied: scipy>=1.8 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (1.11.4)
Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2>=2.9->folium) (2.1.5)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas!=1.5.0,>=1.4->mapclassify) (2023.4)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/dist-packages (from pandas!=1.5.0,>=1.4->mapclassify) (2024.1)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)
Requirement already satisfied: joblib>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from scikit-learn>=1.0->mapclassify) (1.4.2)
Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from scikit-learn>=1.0->mapclassify) (3.5.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (3.7)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (2.0.7)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (2024.6.2)
In [ ]:
import osmnx as ox
from shapely.geometry import Point
In [ ]:
address = "PJATK Warszawa"
lat, lon = ox.geocode(address)

# Create a GeoDataFrame out of the coordinates
origin = gpd.GeoDataFrame({"geometry": [Point(lon, lat)], "name": "PJATK Warszawa", "id": [0]}, index=[0], crs="epsg:4326")
In [ ]:
import geopandas as gpd
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.graph_objs as go
import pyproj
import folium

BUGGING STUFF¶

In [ ]:
import geopandas as gpd
pop_grid = gpd.read_file('/content/drive/MyDrive/Projekt zaliczeniowy/250^2 IDWx4 grid Waw.gpkg')
pop_grid = pop_grid.rename(columns={'DN': 'zaludnienie',})
pop_grid.head(1)
Out[ ]:
zaludnienie geometry
0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752...

Wykres gęstość zaludnienia (ekstrapolacja)¶

In [ ]:
f = folium.Figure(width=1200, height=600)
m = pop_grid.explore("zaludnienie", cmap="Greens", max_zoom=13, tiles="Cartodb Positron")
# m = origin.explore(m=m, color="red", marker_kwds={"radius": 10})
m.add_to(f)
f
Out[ ]:
In [ ]:
points = pop_grid.copy()

# Set the CRS for buffer calculations (assuming EPSG:4326)
points.geometry.set_crs('EPSG:4326', inplace=True)

# Reproject to a projected CRS (e.g., EPSG:3857)
# points = points.to_crs(crs='EPSG:3857')

# Now calculate centroids without the warning
points["geometry"] = points.centroid
<ipython-input-14-e73cd62b9592>:10: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

  points["geometry"] = points.centroid
In [ ]:
points.to_crs(pyproj.CRS.from_epsg(4326), inplace=True)
In [ ]:
points = points.reset_index()
points = points.rename(columns={"index": "id", })
points.head(1)
Out[ ]:
id zaludnienie geometry
0 0 508 POINT (20.95278 52.36861)
In [ ]:
import datetime
from r5py import TravelTimeMatrixComputer, TransportMode

travel_time_matrix_computer = TravelTimeMatrixComputer(
    transport_network,
    origins=origin,
    destinations=points,
    departure=datetime.datetime(2024,6,8,18,30),
    transport_modes=[TransportMode.TRANSIT, TransportMode.WALK]
)
/usr/local/lib/python3.10/dist-packages/r5py/r5/regional_task.py:223: RuntimeWarning: Departure time 2024-06-08 18:30:00 is outside of the time range covered by currently loaded GTFS data sets.
  warnings.warn(
In [ ]:
travel_time_matrix = travel_time_matrix_computer.compute_travel_times()
travel_time_matrix.head(1)
Out[ ]:
from_id to_id travel_time
0 0 0 91.0
In [ ]:
pop_grid = pop_grid.reset_index()
pop_grid = pop_grid.rename(columns={"index": "id", })
pop_grid.head(1)
Out[ ]:
id zaludnienie geometry
0 0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752...
In [ ]:
travel_time_df = pop_grid.merge(travel_time_matrix, left_on="id", right_on="to_id")
travel_time_df = travel_time_df.rename(columns={"travel_time": "travel_time_TRANSIT", })
travel_time_df.head()
Out[ ]:
id zaludnienie geometry from_id to_id travel_time_TRANSIT
0 0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 91.0
1 1 491 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 1 89.0
2 2 300 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 2 87.0
3 3 110 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 3 79.0
4 4 157 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 4 91.0

Wykres czas podróży do PJATK transportem publicznym¶

In [ ]:
fig, ax = plt.subplots(figsize=(9, 9))
travel_time_df.plot(column="travel_time_TRANSIT", cmap="RdYlBu", scheme="equal_interval", k=13, legend=True, ax=ax)
origin.to_crs(crs=travel_time_df.crs).plot(ax=ax, color="green", markersize=40)
ax.set_title(f"Travel time by public transport to PJATK")
plt.show()
No description has been provided for this image

To samo, tylko w folium

In [ ]:
f = folium.Figure(width=1200, height=600)
m = travel_time_df.explore("travel_time_TRANSIT", cmap="RdYlBu", max_zoom=13, tiles="Cartodb Positron")
m = origin.explore(m=m, color="red", marker_kwds={"radius": 10})
m.add_to(f)
f
Out[ ]:
In [ ]:
travel_time_matrix_computer_b = TravelTimeMatrixComputer(
    transport_network,
    origins=origin,
    destinations=points,
    departure=datetime.datetime(2024,6,8,18,30),
    transport_modes=[TransportMode.BICYCLE,]
)
In [ ]:
travel_time_matrix = travel_time_matrix_computer_b.compute_travel_times()
travel_time_matrix.head(1)
Out[ ]:
from_id to_id travel_time
0 0 0 118.0
In [ ]:
travel_time_df = travel_time_df.merge(travel_time_matrix, left_on="id", right_on="to_id")
travel_time_df = travel_time_df.rename(columns={"travel_time": "travel_time_BIKE", })
travel_time_df.head()
Out[ ]:
id zaludnienie geometry from_id_x to_id_x travel_time_TRANSIT from_id_y to_id_y travel_time_BIKE
0 0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 91.0 0 0 118.0
1 1 491 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 1 89.0 0 1 120.0
2 2 300 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 2 87.0 0 2 121.0
3 3 110 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 3 79.0 0 3 NaN
4 4 157 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 4 91.0 0 4 NaN
In [ ]:
travel_time_df['difference'] = travel_time_df['travel_time_TRANSIT'] - travel_time_df['travel_time_BIKE']
In [ ]:
travel_time_df['difference'].value_counts().head()
Out[ ]:
difference
 0.0    262
-4.0    253
-3.0    251
-6.0    245
-2.0    238
Name: count, dtype: int64

Wykres różnica między czasem podróży rowerem a transportem publicznym¶

In [ ]:
import folium

f = folium.Figure(width=1200, height=600)
m = travel_time_df.explore("difference", cmap="RdBu_r", max_zoom=13, tiles="Cartodb Positron")
m = origin.explore(m=m, color="red", marker_kwds={"radius": 10})
m.add_to(f)
f
Out[ ]:

Usługi¶

In [ ]:
amenities = ["library"]
query = ["Warsaw, Poland",]

libraries = ox.features_from_place(query, tags={"amenity": amenities})
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

libraries.head()
/usr/local/lib/python3.10/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
  and should_run_async(code)
Out[ ]:
addr:city addr:housenumber addr:postcode addr:street amenity contact:email contact:phone name opening_hours operator ... name:sq name:sr name:tr name:udm name:uk name:vi name:zh name:zh-Hans name:zh-Hant type
element_type osmid
node 278609792 Warszawa 71 02-679 Zygmunta Modzelewskiego library nr84@bpmokotow.waw.pl +48 22 844 62 71 Wypożyczalnia dla Dorosłych i Młodzieży Nr 84 Mo,Tu,Fr 14:00-19:00; We,Th 11:00-16:00 Biblioteka Publiczna m.st. Warszawy ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
312081254 Warszawa 3 01-864 Włodzimierza Perzyńskiego library NaN NaN Biblioteka Publiczna m.st. Warszawy Dzielnicy ... Mo,Tu 10:00-16:00; We-Fr 12:00-19:00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
331106257 Warszawa 35 02-030 Grójecka library NaN NaN Wypożyczalnia dla Dorosłych i Młodzieży Nr 23 Mo,We,Fr 13:00-19:00; Tu,Th 09:00-15:00; PH off Biblioteka Publiczna m.st. Warszawy ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
376053555 NaN 9/15 NaN Marszałkowska library NaN NaN Wypożyczalnia dla Dorosłych i Młodzieży nr 54 Mo-Fr 10:00-19:00 Biblioteka Publiczna w Dzielnicy Śródmieście m... ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
410399923 Warszawa 17 01-381 Powstańców Śląskich library NaN NaN Czytelnia nr XVII Mo-We, Fr 10:00-19:30; Th 10:00-17:00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

5 rows × 115 columns

In [ ]:
libraries["geometry"] = libraries.centroid
<ipython-input-31-b84e84f7ddfe>:1: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

  libraries["geometry"] = libraries.centroid
In [ ]:
ax = libraries.plot()
ax
Out[ ]:
<Axes: >
No description has been provided for this image

coś dziwnego się tu wydarzyło, normalnie powinno pokazać wiele bibliotek w Warszawie

In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

libraries = libraries.reset_index()
libraries["id"] = libraries.index
libraries.head()
Out[ ]:
element_type osmid addr:city addr:housenumber addr:postcode addr:street amenity contact:email contact:phone name ... name:sr name:tr name:udm name:uk name:vi name:zh name:zh-Hans name:zh-Hant type id
0 node 278609792 Warszawa 71 02-679 Zygmunta Modzelewskiego library nr84@bpmokotow.waw.pl +48 22 844 62 71 Wypożyczalnia dla Dorosłych i Młodzieży Nr 84 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
1 node 312081254 Warszawa 3 01-864 Włodzimierza Perzyńskiego library NaN NaN Biblioteka Publiczna m.st. Warszawy Dzielnicy ... ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 1
2 node 331106257 Warszawa 35 02-030 Grójecka library NaN NaN Wypożyczalnia dla Dorosłych i Młodzieży Nr 23 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 2
3 node 376053555 NaN 9/15 NaN Marszałkowska library NaN NaN Wypożyczalnia dla Dorosłych i Młodzieży nr 54 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 3
4 node 410399923 Warszawa 17 01-381 Powstańców Śląskich library NaN NaN Czytelnia nr XVII ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 4

5 rows × 118 columns

In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

travel_time_matrix_computer = TravelTimeMatrixComputer(
    transport_network,
    origins=libraries,
    destinations=points,
    departure=datetime.datetime(2024,6,8,18,30),
    transport_modes=[TransportMode.TRANSIT, TransportMode.WALK],
)
travel_time_matrix = travel_time_matrix_computer.compute_travel_times()
/usr/local/lib/python3.10/dist-packages/r5py/r5/regional_task.py:223: RuntimeWarning: Departure time 2024-06-08 18:30:00 is outside of the time range covered by currently loaded GTFS data sets.
  warnings.warn(
In [ ]:
travel_time_matrix.shape
Out[ ]:
(1879460, 3)
In [ ]:
# Find out the travel time to closest library
closest_library = travel_time_matrix.groupby("to_id")["travel_time"].min().reset_index()
closest_library = closest_library.rename(columns={'travel_time':'tt_to_closest_library'})
print(closest_library.shape)
closest_library.head()
(8543, 2)
Out[ ]:
to_id tt_to_closest_library
0 0 51.0
1 1 56.0
2 2 54.0
3 3 46.0
4 4 37.0
In [ ]:
travel_time_df = travel_time_df.merge(closest_library, left_on="id", right_on='to_id')
In [ ]:
travel_time_df.head(3)
Out[ ]:
id zaludnienie geometry from_id_x to_id_x travel_time_TRANSIT from_id_y to_id_y travel_time_BIKE difference to_id tt_to_closest_library
0 0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 91.0 0 0 118.0 -27.0 0 51.0
1 1 491 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 1 89.0 0 1 120.0 -31.0 1 56.0
2 2 300 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 2 87.0 0 2 121.0 -34.0 2 54.0

BIBLIOTEKI - Wykres czas podróży do najbliższej biblioteki¶

In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

fig, ax = plt.subplots(figsize=(9, 9))
travel_time_df.plot(column="tt_to_closest_library", cmap="RdYlBu", scheme="natural_breaks", k=12, legend=True, ax=ax)
origin.to_crs(crs=travel_time_df.crs).plot(ax=ax, color="green", markersize=40)
ax.set_title(f"Travel time to closest libary in minutes.");
plt.show()
No description has been provided for this image

Test z ilością restauracji w zasięgu 15 minut¶

In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

amenities = ['restaurant', 'pub', 'bar']
query = ["Warsaw, Poland",]

restaurants = ox.features_from_place(query, tags={"amenity": amenities[0]})
pubs = ox.features_from_place(query, tags={"amenity": amenities[1]})
bars = ox.features_from_place(query, tags={"amenity": amenities[2]})
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/pandas/core/frame.py:717: DeprecationWarning: Passing a BlockManager to GeoDataFrame is deprecated and will raise in a future version. Use public APIs instead.
  warnings.warn(
In [ ]:
print(restaurants.shape)
(1941, 198)
/usr/local/lib/python3.10/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
  and should_run_async(code)
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

print(restaurants.shape)
display(restaurants.head(3))
print(pubs.shape)
display(pubs.head(3))
print(bars.shape)
display(bars.head(3))
(1941, 198)
addr:city addr:housenumber addr:street amenity geometry addr:postcode check_date:opening_hours cuisine name opening_hours ... source:building old_addr:housenumber wikidata drive_in nohousenumber addr:source building:part roof:levels roof:orientation building:material
element_type osmid
node 31005854 Warszawa 110 Aleja Krakowska restaurant POINT (20.94595 52.17691) NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
201830837 Warszawa 37 Barska restaurant POINT (20.97434 52.21898) 02-315 2023-06-30 pizza Pizzeria na Barskiej Mo-Su 12:00-22:00 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
247441607 Warszawa 46 Aleja Jerzego Waszyngtona restaurant POINT (21.06198 52.23995) 03-910 2022-08-22 pizza Chicago's Pizza Mo-Th 11:00-23:00; Fr-Sa 11:00-24:00; Su 11:00... ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

3 rows × 198 columns

(152, 77)
addr:city addr:country addr:housenumber addr:postcode addr:street amenity check_date email name opening_hours ... microbrewery shop source:addr survey:date source mobile nodes building building:levels height
element_type osmid
node 248569875 Warszawa PL 177 02-555 Aleja Niepodległości pub 2024-03-23 pub@zielonages.pl Zielona Gęś 12:00+ ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
261659066 NaN NaN 54 NaN Aleja Komisji Edukacji Narodowej pub NaN NaN Klubokawiarnia KEN 54 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
280333661 NaN NaN NaN NaN NaN pub NaN NaN Bez Słowa NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

3 rows × 77 columns

(294, 105)
addr:city addr:housenumber addr:street amenity check_date description facebook name opening_hours outdoor_seating ... heritage heritage:operator historic motorcycle motorcycle:theme old_name ref:gez theme indoor ref
element_type osmid
node 248197975 Warszawa 4 Henryka Sienkiewicza bar 2023-09-05 Multitap bar thetapswarsaw The Taps Mo-We, Su 15:00-00:00; Th 15:00-01:00; Fr, Sa ... yes ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
302711831 NaN NaN NaN bar 2024-04-05 NaN NaN Inspector Lounge NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
306550336 NaN 5 Chmielna bar 2022-07-22 NaN NaN Zakątek NaN yes ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

3 rows × 105 columns

Sprawdzenie czy są powtórzenia:

In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

rest_reset = restaurants.reset_index()
pubs_reset = pubs.reset_index()
bars_reset = bars.reset_index()
In [ ]:
overlap_rest_pubs = rest_reset['osmid'][rest_reset['osmid'].isin(pubs_reset['osmid'])]
In [ ]:
overlap_rest_bars = rest_reset['osmid'][rest_reset['osmid'].isin(bars_reset['osmid'])]
In [ ]:
overlap_bars_pubs = pubs_reset['osmid'][pubs_reset['osmid'].isin(bars_reset['osmid'])]
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

display(overlap_rest_pubs)
display(overlap_rest_bars)
display(overlap_bars_pubs)
Series([], Name: osmid, dtype: int64)
Series([], Name: osmid, dtype: int64)
Series([], Name: osmid, dtype: int64)

Wygląda na to, że nie ma powtórzeń.

In [ ]:
import numpy as np
length = bars.shape[0]
print(f'Total records: {length}')

try:
  for i in np.array(bars.columns.tolist()).reshape(15,7):
    hd = bars[i].head(3)

    nans =  [bars[j].isna().sum() for j in hd.columns]
    # nans_perc = [(str(int(round(df[j].isna().sum() / length * 100, 4))) + '%') for j in hd.columns]

    nans_perc = [ round(bars[j].isna().sum() / length, 3) * 100 for j in hd.columns ]

    # nans_perc = [round(df[j].isna().sum() / length, 3) * 100 for j in hd.columns]
    uniques = [bars[j].nunique() for j in hd.columns]
    typ = [ bars[bars[j].notnull()][j].dtype for j in hd.columns]

    # print(typ)

    hd.loc[len(hd)] = typ
    hd.loc[len(hd)] = nans
    hd.loc[len(hd)] = nans_perc
    hd.loc[len(hd)] = uniques

    hd.loc[len(hd)-3] = hd.loc[len(hd)-3].astype('int')
    hd.loc[len(hd)-1] = hd.loc[len(hd)-1].astype('int')

    hd = hd.rename(index={int(len(hd)-4): 'Data type',
                          int(len(hd)-3): 'Total NaN',
                          int(len(hd)-2): '% NaN',
                          int(len(hd)-1): 'Unique values',
                          })

    display(hd)
    print(' ')
except:
  print('Coś nie pykło')
Total records: 294
addr:city addr:housenumber addr:street amenity check_date description facebook
(node, 248197975) Warszawa 4 Henryka Sienkiewicza bar 2023-09-05 Multitap bar thetapswarsaw
(node, 302711831) NaN NaN NaN bar 2024-04-05 NaN NaN
(node, 306550336) NaN 5 Chmielna bar 2022-07-22 NaN NaN
Data type object object object object object object object
Total NaN 212 147 141 0 138 289 279
% NaN 72.1 50.0 48.0 0.0 46.9 98.3 94.9
Unique values 2 75 68 1 77 3 15
 
name opening_hours outdoor_seating phone toilets:wheelchair wheelchair geometry
(node, 248197975) The Taps Mo-We, Su 15:00-00:00; Th 15:00-01:00; Fr, Sa ... yes +48601707407 yes limited POINT (21.0125356 52.2344797)
(node, 302711831) Inspector Lounge NaN NaN NaN NaN NaN POINT (21.0064856 52.2361758)
(node, 306550336) Zakątek NaN yes NaN NaN no POINT (21.0182611 52.2328789)
Data type object object object object object object geometry
Total NaN 12 208 201 258 291 152 0
% NaN 4.1 70.7 68.4 87.8 99.0 51.7 0.0
Unique values 273 83 3 36 2 3 294
 
level addr:postcode email website addr:city:en note access
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) -1 NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 260 218 280 236 292 293 292
% NaN 88.4 74.1 95.2 80.3 99.3 99.7 99.3
Unique values 5 40 14 56 1 1 2
 
addr:floor aeroway leisure indoor_seating cuisine alt_name brewery
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 289 292 290 283 287 288 284
% NaN 98.3 99.3 98.6 96.3 97.6 98.0 96.6
Unique values 3 1 3 1 5 6 6
 
payment:cash payment:credit_cards payment:debit_cards contact:facebook internet_access smoking addr:city:simc
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 292 289 291 286 288 283 287
% NaN 99.3 98.3 99.0 97.3 98.0 96.3 97.6
Unique values 1 1 1 8 2 3 2
 
source:addr opening_hours:signed addr:housename internet_access:fee brand brand:website brand:wikidata
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 288 287 291 293 286 291 287
% NaN 98.0 97.6 99.0 99.7 97.3 99.0 97.6
Unique values 2 1 2 1 3 1 2
 
brand:wikipedia entrance operator name:pl check_date:opening_hours name:en sport
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 291 293 292 289 290 286 292
% NaN 99.0 99.7 99.3 98.3 98.6 97.3 99.3
Unique values 1 1 2 5 3 6 2
 
website_1 official_name source hookah short_name diet:vegetarian payment:american_express
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 293 292 220 293 293 293 293
% NaN 99.7 99.3 74.8 99.7 99.7 99.7 99.7
Unique values 1 2 4 1 1 1 1
 
payment:apple_pay payment:blik payment:diners_club payment:discover_card payment:google_pay payment:jcb payment:maestro
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 293 293 293 293 293 293 293
% NaN 99.7 99.7 99.7 99.7 99.7 99.7 99.7
Unique values 1 1 1 1 1 1 1
 
payment:mastercard payment:mastercard_contactless payment:unionpay payment:visa payment:visa_contactless payment:visa_electron reservation
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 292 293 293 292 293 293 292
% NaN 99.3 99.7 99.7 99.3 99.7 99.7 99.3
Unique values 1 1 1 1 1 1 2
 
name:ru name:uk start_date access:covid19 public_transport shop lgbtq
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 293 292 292 293 293 289 293
% NaN 99.7 99.3 99.3 99.7 99.7 98.3 99.7
Unique values 1 1 2 1 1 1 1
 
noname contact:email contact:phone min_age wine contact:instagram air_conditioning
(node, 248197975) NaN NaN NaN NaN NaN NaN NaN
(node, 302711831) NaN NaN NaN NaN NaN NaN NaN
(node, 306550336) NaN NaN NaN NaN NaN NaN NaN
Data type object object object object object object object
Total NaN 291 293 293 292 293 293 293
% NaN 99.0 99.7 99.7 99.3 99.7 99.7 99.7
Unique values 1 1 1 1 1 1 1
 
Coś nie pykło
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)


restaurants["geometry"] = restaurants.centroid
bars["geometry"] = bars.centroid
pubs["geometry"] = pubs.centroid
<ipython-input-49-283dd92223be>:4: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

  restaurants["geometry"] = restaurants.centroid
<ipython-input-49-283dd92223be>:5: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

  bars["geometry"] = bars.centroid
<ipython-input-49-283dd92223be>:6: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

  pubs["geometry"] = pubs.centroid
In [ ]:
bars.shape[0]
Out[ ]:
294
In [ ]:
msize = 8

fig, ax = plt.subplots(figsize=(9, 9))

restaurants.plot(color='#636EFA', label=f'Restauracje ({restaurants.shape[0]})', markersize=msize, ax=ax)
bars.plot(color='#EF553B', label=f'Bary ({bars.shape[0]})', markersize=msize, ax=ax)
pubs.plot(color='#00CC96', label=f'Puby ({pubs.shape[0]})', markersize=msize, ax=ax)

ax.legend()

plt.show()
No description has been provided for this image
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

restaurants = restaurants.reset_index()
restaurants["id"] = restaurants.index

bars = bars.reset_index()
bars["id"] = bars.index

pubs = pubs.reset_index()
pubs["id"] = pubs.index
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

restaurants.head()
Out[ ]:
element_type osmid addr:city addr:housenumber addr:street amenity geometry addr:postcode check_date:opening_hours cuisine ... old_addr:housenumber wikidata drive_in nohousenumber addr:source building:part roof:levels roof:orientation building:material id
0 node 31005854 Warszawa 110 Aleja Krakowska restaurant POINT (20.94595 52.17691) NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
1 node 201830837 Warszawa 37 Barska restaurant POINT (20.97434 52.21898) 02-315 2023-06-30 pizza ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 1
2 node 247441607 Warszawa 46 Aleja Jerzego Waszyngtona restaurant POINT (21.06198 52.23995) 03-910 2022-08-22 pizza ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 2
3 node 247461210 Warszawa 26 Widok restaurant POINT (21.01211 52.23124) 00-023 NaN pizza ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 3
4 node 248200343 NaN 3/5 Foksal restaurant POINT (21.02340 52.23409) NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 4

5 rows × 201 columns

In [ ]:
def polygon_to_point(geometry):
    if geometry.type == 'Polygon':
        return geometry.centroid
    else:
        return geometry
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

restaurants['geometry'] = restaurants['geometry'].apply(polygon_to_point)
/usr/local/lib/python3.10/dist-packages/geopandas/geoseries.py:645: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version.  Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``.
  result = super().apply(func, convert_dtype=convert_dtype, args=args, **kwargs)
<ipython-input-54-7c5a00dccd47>:2: ShapelyDeprecationWarning: The 'type' attribute is deprecated, and will be removed in the future. You can use the 'geom_type' attribute instead.
  if geometry.type == 'Polygon':

Travel time matrices - restaurants, pubs, bars¶

In [ ]:
create_matrices = True
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

if create_matrices:
  travel_time_matrix_computer = TravelTimeMatrixComputer(
      transport_network,
      origins=restaurants,
      destinations=points,
      departure=datetime.datetime(2024,6,8,18,30),
      transport_modes=[TransportMode.TRANSIT, TransportMode.WALK],
  )

  travel_time_matrix = travel_time_matrix_computer.compute_travel_times()
  print(f'Full matrix shape: {travel_time_matrix.shape}')

  display(travel_time_matrix.head(3))

  cut_tt_matrix = travel_time_matrix.query('travel_time <= 15')
  print(f'Cut to 15 minutes matrix shape: {cut_tt_matrix.shape}')

else:
  cut_tt_matrix = gpd.read_file('/content/drive/MyDrive/Projekt zaliczeniowy/Matrices/restaurant_travel_time_matrix_CUT15.csv')
/usr/local/lib/python3.10/dist-packages/r5py/r5/regional_task.py:223: RuntimeWarning: Departure time 2024-06-08 18:30:00 is outside of the time range covered by currently loaded GTFS data sets.
  warnings.warn(
Full matrix shape: (16581963, 3)
from_id to_id travel_time
0 0 0 94.0
1 0 1 95.0
2 0 2 93.0
Cut to 15 minutes matrix shape: (64188, 3)
In [ ]:
# cut_tt_matrix.to_csv('restaurant_travel_time_matrix_CUT15 v2.csv')
travel_time_matrix.to_csv('restaurant_travel_time_matrix v2.csv')
<frozen importlib._bootstrap>:914: ImportWarning: _PyDrive2ImportHook.find_spec() not found; falling back to find_module()
<frozen importlib._bootstrap>:914: ImportWarning: _PyDriveImportHook.find_spec() not found; falling back to find_module()
<frozen importlib._bootstrap>:914: ImportWarning: _GenerativeAIImportHook.find_spec() not found; falling back to find_module()
<frozen importlib._bootstrap>:914: ImportWarning: _OpenCVImportHook.find_spec() not found; falling back to find_module()
<frozen importlib._bootstrap>:914: ImportWarning: APICoreClientInfoImportHook.find_spec() not found; falling back to find_module()
<frozen importlib._bootstrap>:914: ImportWarning: _BokehImportHook.find_spec() not found; falling back to find_module()
<frozen importlib._bootstrap>:914: ImportWarning: _AltairImportHook.find_spec() not found; falling back to find_module()
In [ ]:
n_rest = cut_tt_matrix.groupby('to_id').size()
n_rest
Out[ ]:
to_id
16      1
18      1
19      1
20      1
40      1
       ..
8425    1
8426    2
8427    1
8428    1
8440    3
Length: 5050, dtype: int64
In [ ]:
# n_rest.rename('id')
In [ ]:
travel_time_df_copy = travel_time_df.copy()
In [ ]:
travel_time_df_copy['n_restauracji'] = travel_time_df.index.map(n_rest).fillna(0).astype(int)
In [ ]:
travel_time_df_copy.head(3)
Out[ ]:
id zaludnienie geometry from_id_x to_id_x travel_time_TRANSIT from_id_y to_id_y travel_time_BIKE difference to_id tt_to_closest_library n_restauracji
0 0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 91.0 0 0 118.0 -27.0 0 51.0 0
1 1 491 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 1 89.0 0 1 120.0 -31.0 1 56.0 0
2 2 300 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 2 87.0 0 2 121.0 -34.0 2 54.0 0
In [ ]:
travel_time_df_copy['n_restauracji'].value_counts()
Out[ ]:
n_restauracji
0      3493
1       905
2       599
3       477
4       326
       ... 
132       1
117       1
52        1
113       1
125       1
Name: count, Length: 160, dtype: int64
In [ ]:
fig, ax = plt.subplots(figsize=(9, 9))
travel_time_df_copy.plot(column="n_restauracji", scheme="natural_breaks", k=12, legend=True, ax=ax)
ax.set_title(f"Ilość w restauracji w zasięgu 15 minut");
plt.show()
No description has been provided for this image

Kontynuacja dla barów i pubów¶

In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

bars['geometry'] = bars['geometry'].apply(polygon_to_point)
pubs['geometry'] = pubs['geometry'].apply(polygon_to_point)
/usr/local/lib/python3.10/dist-packages/geopandas/geoseries.py:645: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version.  Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``.
  result = super().apply(func, convert_dtype=convert_dtype, args=args, **kwargs)
<ipython-input-54-7c5a00dccd47>:2: ShapelyDeprecationWarning: The 'type' attribute is deprecated, and will be removed in the future. You can use the 'geom_type' attribute instead.
  if geometry.type == 'Polygon':
/usr/local/lib/python3.10/dist-packages/geopandas/geoseries.py:645: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version.  Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``.
  result = super().apply(func, convert_dtype=convert_dtype, args=args, **kwargs)
<ipython-input-54-7c5a00dccd47>:2: ShapelyDeprecationWarning: The 'type' attribute is deprecated, and will be removed in the future. You can use the 'geom_type' attribute instead.
  if geometry.type == 'Polygon':
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

if create_matrices:
  travel_time_matrix_computer = TravelTimeMatrixComputer(
      transport_network,
      origins=bars,
      destinations=points,
      departure=datetime.datetime(2024,6,8,18,30),
      transport_modes=[TransportMode.TRANSIT, TransportMode.WALK],
  )

  travel_time_matrix = travel_time_matrix_computer.compute_travel_times()
/usr/local/lib/python3.10/dist-packages/r5py/r5/regional_task.py:223: RuntimeWarning: Departure time 2024-06-08 18:30:00 is outside of the time range covered by currently loaded GTFS data sets.
  warnings.warn(
In [ ]:
travel_time_matrix.shape
Out[ ]:
(2511642, 3)
In [ ]:
travel_time_matrix.to_csv('bars_travel_time_matrix.csv')
In [ ]:
cut_tt_matrix = travel_time_matrix.query('travel_time <= 15')
In [ ]:
cut_tt_matrix.to_csv('bars_travel_time_matrix_CUT15.csv')
In [ ]:
n_bars = cut_tt_matrix.groupby('to_id').size()
In [ ]:
n_bars
Out[ ]:
to_id
742     1
745     1
749     1
792     1
793     1
       ..
8103    2
8104    2
8105    2
8106    2
8151    1
Length: 1938, dtype: int64
In [ ]:
travel_time_df_copy['n_barow'] = travel_time_df.index.map(n_bars).fillna(0).astype(int)
In [ ]:
travel_time_df_copy.head(1)
Out[ ]:
id zaludnienie geometry from_id_x to_id_x travel_time_TRANSIT from_id_y to_id_y travel_time_BIKE difference to_id tt_to_closest_library n_restauracji n_barow
0 0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 91.0 0 0 118.0 -27.0 0 51.0 0 0
In [ ]:
fig, ax = plt.subplots(figsize=(9, 9))
travel_time_df_copy.plot(column="n_barow", scheme="natural_breaks", k=12, legend=True, ax=ax)
ax.set_title(f"Ilość w barów w zasięgu 15 minut");
plt.show()
No description has been provided for this image
In [ ]:
warnings.filterwarnings('ignore', category=DeprecationWarning)

if create_matrices:
  travel_time_matrix_computer = TravelTimeMatrixComputer(
      transport_network,
      origins=pubs,
      destinations=points,
      departure=datetime.datetime(2024,6,8,18,30),
      transport_modes=[TransportMode.TRANSIT, TransportMode.WALK],
  )

  travel_time_matrix = travel_time_matrix_computer.compute_travel_times()
/usr/local/lib/python3.10/dist-packages/r5py/r5/regional_task.py:223: RuntimeWarning: Departure time 2024-06-08 18:30:00 is outside of the time range covered by currently loaded GTFS data sets.
  warnings.warn(
In [ ]:
travel_time_matrix.shape
Out[ ]:
(1298536, 3)
In [ ]:
travel_time_matrix.to_csv('pubs_travel_time_matrix.csv')
In [ ]:
cut_tt_matrix = travel_time_matrix.query('travel_time <= 15')
In [ ]:
cut_tt_matrix.to_csv('pubs_travel_time_matrix_CUT15.csv')
In [ ]:
n_pubs = cut_tt_matrix.groupby('to_id').size()
In [ ]:
travel_time_df_copy['n_pubow'] = travel_time_df.index.map(n_pubs).fillna(0).astype(int)
In [ ]:
travel_time_df_copy.head(1)
Out[ ]:
id zaludnienie geometry from_id_x to_id_x travel_time_TRANSIT from_id_y to_id_y travel_time_BIKE difference to_id tt_to_closest_library n_restauracji n_barow n_pubow
0 0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 91.0 0 0 118.0 -27.0 0 51.0 0 0 0
In [ ]:
fig, ax = plt.subplots(figsize=(9, 9))
travel_time_df_copy.plot(column="n_pubow", scheme="natural_breaks", k=12, legend=True, ax=ax)
ax.set_title(f"Ilość w pubów w zasięgu 15 minut");
plt.show()
No description has been provided for this image
In [ ]:
travel_time_df_copy.to_csv('travel_time_df_copy.csv')
In [ ]:
travel_time_df_copy['n_gastro'] = travel_time_df_copy['n_restauracji'] + travel_time_df_copy['n_barow'] + travel_time_df_copy['n_pubow']
In [ ]:
fig, ax = plt.subplots(figsize=(9, 9))
travel_time_df_copy.plot(column="n_gastro", scheme="natural_breaks", k=12, legend=True, ax=ax)
ax.set_title(f"Suma restauracji, pubów i barów w zasięgu 15 minut");
plt.show()
No description has been provided for this image

Dominujące gastro¶

In [ ]:
travel_time_df_copy.head()
Out[ ]:
id zaludnienie geometry from_id_x to_id_x travel_time_TRANSIT from_id_y to_id_y travel_time_BIKE difference to_id tt_to_closest_library n_restauracji n_barow n_pubow n_gastro
0 0 508 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 91.0 0 0 118.0 -27.0 0 51.0 0 0 0 0
1 1 491 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 1 89.0 0 1 120.0 -31.0 1 56.0 0 0 0 0
2 2 300 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 2 87.0 0 2 121.0 -34.0 2 54.0 0 0 0 0
3 3 110 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 3 79.0 0 3 NaN NaN 3 46.0 0 0 0 0
4 4 157 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 4 91.0 0 4 NaN NaN 4 37.0 0 0 0 0
In [ ]:
gastro_df = travel_time_df_copy[['id', 'geometry', 'n_restauracji', 'n_barow', 'n_pubow', 'n_gastro']].copy()
gastro_df
Out[ ]:
id geometry n_restauracji n_barow n_pubow n_gastro
0 0 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 0 0
1 1 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 0 0 0
2 2 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 0 0 0
3 3 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 0 0 0
4 4 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 0 0 0
... ... ... ... ... ... ...
8538 8538 POLYGON ((21.07731 52.10113, 21.07721 52.09889... 0 0 0 0
8539 8539 POLYGON ((21.08094 52.10107, 21.08084 52.09883... 0 0 0 0
8540 8540 POLYGON ((21.08457 52.10100, 21.08447 52.09877... 0 0 0 0
8541 8541 POLYGON ((21.07721 52.09889, 21.07711 52.09666... 0 0 0 0
8542 8542 POLYGON ((21.08084 52.09883, 21.08074 52.09659... 0 0 0 0

8543 rows × 6 columns

In [ ]:
gastro_df['rest_%'] = gastro_df['n_restauracji'] / gastro_df['n_gastro']
gastro_df['bars_%'] = gastro_df['n_barow'] / gastro_df['n_gastro']
gastro_df['pubs_%'] = gastro_df['n_pubow'] / gastro_df['n_gastro']
In [ ]:
gastro_df = gastro_df.fillna(0)
In [ ]:
gastro_df = gastro_df.rename(columns={
    'n_restauracji':'n_rest',
    'n_barow':'n_bars',
    'n_pubow':'n_pubs',
})
In [ ]:
gastro_df.head()
Out[ ]:
id geometry n_rest n_bars n_pubs n_gastro rest_% bars_% pubs_%
0 0 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 0 0 0.0 0.0 0.0
1 1 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 0 0 0 0.0 0.0 0.0
2 2 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 0 0 0 0.0 0.0 0.0
3 3 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 0 0 0 0.0 0.0 0.0
4 4 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 0 0 0 0.0 0.0 0.0
In [ ]:
gastro_df['rest_norm'] = (gastro_df['n_rest'] - gastro_df['n_rest'].min()) / (gastro_df['n_rest'].max() - gastro_df['n_rest'].min())
gastro_df['bars_norm'] = (gastro_df['n_bars'] - gastro_df['n_bars'].min()) / (gastro_df['n_bars'].max() - gastro_df['n_bars'].min())
gastro_df['pubs_norm'] = (gastro_df['n_pubs'] - gastro_df['n_pubs'].min()) / (gastro_df['n_pubs'].max() - gastro_df['n_pubs'].min())
In [ ]:
gastro_df.head()
Out[ ]:
id geometry n_rest n_bars n_pubs n_gastro rest_% bars_% pubs_% rest_norm bars_norm pubs_norm
0 0 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0
1 1 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0
2 2 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0
3 3 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0
4 4 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0
In [ ]:
norms = gastro_df.iloc[:, -3:]
gastro_df = gastro_df.iloc[:, :9]
In [ ]:
norms.head()
Out[ ]:
rest_norm bars_norm pubs_norm
0 0.0 0.0 0.0
1 0.0 0.0 0.0
2 0.0 0.0 0.0
3 0.0 0.0 0.0
4 0.0 0.0 0.0
In [ ]:
most_prevalent_type = norms.idxmax(axis=1)
norms['check'] = norms[['rest_norm', 'bars_norm', 'pubs_norm']].max(axis=1)
norms['most_prevalent'] = most_prevalent_type
# norms['check'] = norms['rest_norm'] + norms['bars_norm'] + norms['pubs_norm']
norms.head()
Out[ ]:
rest_norm bars_norm pubs_norm check most_prevalent
0 0.0 0.0 0.0 0.0 rest_norm
1 0.0 0.0 0.0 0.0 rest_norm
2 0.0 0.0 0.0 0.0 rest_norm
3 0.0 0.0 0.0 0.0 rest_norm
4 0.0 0.0 0.0 0.0 rest_norm
In [ ]:
def fix_prevalent(most_prevalent, check):
  if check == 0:
    return 'brak'
  else:
    return most_prevalent
In [ ]:
norms['most_prevalent'] = norms.apply(lambda x: fix_prevalent(x['most_prevalent'], x['check']), axis=1)
In [ ]:
norms['most_prevalent'].value_counts()
Out[ ]:
most_prevalent
rest_norm    3475
brak         3360
pubs_norm    1390
bars_norm     318
Name: count, dtype: int64
In [ ]:
print(norms.shape[0], gastro_df.shape[0])
8543 8543
In [ ]:
gastro_join = gastro_df.join(norms, how='outer', lsuffix='_left', rsuffix='_right')
gastro_join.head()
Out[ ]:
id geometry n_rest n_bars n_pubs n_gastro rest_% bars_% pubs_% rest_norm bars_norm pubs_norm check most_prevalent
0 0 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
1 1 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
2 2 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
3 3 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
4 4 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
In [ ]:
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.patches as mpatches
from shapely.geometry import Polygon

gastro_join_copy = gastro_join.copy()

# Define base colors for each category
base_colors = {
    'rest_norm': '#636EFA',  # Blue
    'bars_norm': '#EF553B',  # Red
    'pubs_norm': '#00CC96',  # Green
    'brak': '#e6e6e6'        # Grey
}

# Define legend labels
legend_labels = {
    'rest_norm': 'Restauracje',
    'bars_norm': 'Bary',
    'pubs_norm': 'Puby',
    'brak': 'None'
}

# Function to generate shades of a base color
def shade_color(base_color, value):
    base_color_rgb = mcolors.hex2color(base_color)
    white_rgb = (1, 1, 1)
    shaded_color = mcolors.to_hex([base_color_rgb[i] * value + white_rgb[i] * (1 - value) for i in range(3)])
    return shaded_color

# Ensure values are between 0 and 1 (if not already normalized)
gastro_join_copy['check'] = gastro_join_copy['check'].clip(0, 1)

# Create a color column based on the category and value
gastro_join_copy['color'] = gastro_join_copy.apply(lambda x: shade_color(base_colors[x['most_prevalent']], x['check']), axis=1)

# Plotting
fig, ax = plt.subplots(1, 1, figsize=(10, 10))

# Plot each category with its specific color and without edges
for category in base_colors.keys():
    subset = gastro_join_copy[gastro_join_copy['most_prevalent'] == category]
    subset.plot(ax=ax, color=subset['color'], edgecolor=None)

# Add legend with custom labels
legend_patches = [mpatches.Patch(color=shade_color(base_colors[category], 0.7), label=legend_labels[category]) for category in base_colors.keys()]
plt.legend(handles=legend_patches)

ax.set_title(f"Dominujący rodzaj gastro (po normalizacji)");

plt.show()
No description has been provided for this image
In [ ]:
import geopandas as gpd
import folium
import matplotlib.colors as mcolors
from shapely.geometry import Polygon

# Sample data creation (replace with your actual data)

gastro_join_copy_fol = gastro_join_copy.query('check >= 0.1')

# Define the base map with CartoDB Positron tiles
f = folium.Figure(width=1200, height=600)
m = folium.Map(location=[gastro_join_copy_fol.geometry.centroid.y.mean(), gastro_join_copy_fol.geometry.centroid.x.mean()], zoom_start=12, tiles='CartoDB Positron')
m.add_to(f)

# Function to style GeoJSON features
def style_function(feature):
    return {
        'fillColor': feature['properties']['color'],
        'color': feature['properties']['color'],
        'weight': 0.5,
        'fillOpacity': 0.7
    }

# Convert GeoDataFrame to GeoJSON format
gastro_geojson = gastro_join_copy_fol.to_json()

# Add GeoJSON layer to the Folium map
folium.GeoJson(
    gastro_geojson,
    style_function=style_function,
    tooltip=folium.GeoJsonTooltip(fields=['most_prevalent', 'check'])
).add_to(m)

# Add legend to the map
legend_html = """
<div style="position: fixed;
            bottom: 50px; left: 50px; width: 150px; height: 100px;
            background-color: white; z-index:9999; font-size:14px;
            border:2px solid grey; padding: 10px;">
     <b>Legenda</b><br>
     <i class="fa fa-square" style="color:#636EFA"></i> Restauracje<br>
     <i class="fa fa-square" style="color:#EF553B"></i> Bary<br>
     <i class="fa fa-square" style="color:#00CC96"></i> Puby<br>
</div>
"""

m.get_root().html.add_child(folium.Element(legend_html))

# Display the map
m.save('map.html')
f
<ipython-input-284-d8a7f9824ce6>:12: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

  m = folium.Map(location=[gastro_join_copy_fol.geometry.centroid.y.mean(), gastro_join_copy_fol.geometry.centroid.x.mean()], zoom_start=12, tiles='CartoDB Positron')
Out[ ]:
In [ ]:
gastro_join_copy.head()
Out[ ]:
id geometry n_rest n_bars n_pubs n_gastro rest_% bars_% pubs_% rest_norm bars_norm pubs_norm check most_prevalent color
0 0 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak #ffffff
1 1 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak #ffffff
2 2 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak #ffffff
3 3 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak #ffffff
4 4 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak #ffffff
In [ ]:
perc = gastro_join_copy[['rest_%', 	'bars_%', 	'pubs_%', 	]].copy()
perc.head(1)
Out[ ]:
rest_% bars_% pubs_%
0 0.0 0.0 0.0
In [ ]:
most_prevalent_perc = perc.idxmax(axis=1)
perc['check_perc'] = perc[['rest_%', 	'bars_%', 	'pubs_%', 	]].max(axis=1)
perc['most_prevalent_perc'] = most_prevalent_perc
In [ ]:
perc['most_prevalent_perc'] = perc.apply(lambda x: fix_prevalent(x['most_prevalent_perc'], x['check_perc']), axis=1)
In [ ]:
perc.head()
Out[ ]:
rest_% bars_% pubs_% check_perc most_prevalent_perc
0 0.0 0.0 0.0 0.0 brak
1 0.0 0.0 0.0 0.0 brak
2 0.0 0.0 0.0 0.0 brak
3 0.0 0.0 0.0 0.0 brak
4 0.0 0.0 0.0 0.0 brak
In [ ]:
print(perc.shape, gastro_join.shape)
(8543, 5) (8543, 14)
In [ ]:
gastro_join.head()
Out[ ]:
id geometry n_rest n_bars n_pubs n_gastro rest_% bars_% pubs_% rest_norm bars_norm pubs_norm check most_prevalent
0 0 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
1 1 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
2 2 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
3 3 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
4 4 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 brak
In [ ]:
gastro_join_perc = gastro_join[['id', 'geometry']].join(perc, how='outer', lsuffix='_left', rsuffix='_right')
In [ ]:
gastro_join_perc.head()
Out[ ]:
id geometry rest_% bars_% pubs_% check_perc most_prevalent_perc
0 0 POLYGON ((20.95100 52.36976, 20.95091 52.36752... 0.0 0.0 0.0 0.0 brak
1 1 POLYGON ((20.95831 52.36964, 20.95821 52.36740... 0.0 0.0 0.0 0.0 brak
2 2 POLYGON ((20.96196 52.36957, 20.96186 52.36734... 0.0 0.0 0.0 0.0 brak
3 3 POLYGON ((20.96561 52.36951, 20.96551 52.36728... 0.0 0.0 0.0 0.0 brak
4 4 POLYGON ((21.05692 52.36796, 21.05681 52.36572... 0.0 0.0 0.0 0.0 brak
In [ ]:
gastro_join_perc['most_prevalent_perc'].value_counts()
Out[ ]:
most_prevalent_perc
rest_%    5034
brak      3360
pubs_%      78
bars_%      71
Name: count, dtype: int64
In [ ]:
gastro_join_perc_copy = gastro_join_perc.copy()

# Define base colors for each category
base_colors = {
    'rest_%': '#636EFA',  # Blue
    'bars_%': '#EF553B',  # Red
    'pubs_%': '#00CC96',  # Green
    'brak': '#e6e6e6'        # Grey
}

# Define legend labels
legend_labels = {
    'rest_%': 'Restaurants',
    'bars_%': 'Bars',
    'pubs_%': 'Pubs',
    'brak': 'None'
}

# Function to generate shades of a base color
def shade_color(base_color, value):
    base_color_rgb = mcolors.hex2color(base_color)
    white_rgb = (1, 1, 1)
    shaded_color = mcolors.to_hex([base_color_rgb[i] * value + white_rgb[i] * (1 - value) for i in range(3)])
    return shaded_color

# Ensure values are between 0 and 1 (if not already normalized)
gastro_join_perc_copy['check_perc'] = gastro_join_perc_copy['check_perc'].clip(0, 1)

# Create a color column based on the category and value
gastro_join_perc_copy['color_perc'] = gastro_join_perc_copy.apply(lambda x: shade_color(base_colors[x['most_prevalent_perc']], x['check_perc']), axis=1)

# Plotting
fig, ax = plt.subplots(1, 1, figsize=(10, 10))

# Plot each category with its specific color and without edges
for category in base_colors.keys():
    subset = gastro_join_perc_copy[gastro_join_perc_copy['most_prevalent_perc'] == category]
    subset.plot(ax=ax, color=subset['color_perc'], edgecolor=None)

# Add legend with custom labels
legend_patches = [mpatches.Patch(color=shade_color(base_colors[category], 0.7), label=legend_labels[category]) for category in base_colors.keys()]
plt.legend(handles=legend_patches)

ax.set_title(f"Dominujący rodzaj gastro (%)");

plt.show()
No description has been provided for this image
In [ ]:
gastro_join_perc_copy = gastro_join_perc.copy()

# Define base colors for each category
base_colors = {
    'rest_%': '#636EFA',  # Blue
    'bars_%': '#EF553B',  # Red
    'pubs_%': '#00CC96',  # Green
    'brak': '#e6e6e6'     # Grey
}

# Define legend labels
legend_labels = {
    'rest_%': 'Restauracje',
    'bars_%': 'Bary',
    'pubs_%': 'Puby',
    'brak': 'brak'
}

# Function to generate shades of a base color
def shade_color(base_color, value):
    base_color_rgb = mcolors.hex2color(base_color)
    white_rgb = (1, 1, 1)
    shaded_color = mcolors.to_hex([base_color_rgb[i] * value + white_rgb[i] * (1 - value) for i in range(3)])
    return shaded_color

# Ensure values are between 0 and 1 (if not already normalized)
gastro_join_perc_copy['check_perc'] = gastro_join_perc_copy['check_perc'].clip(0, 1)

# Create a color column based on the category and value
gastro_join_perc_copy['color_perc'] = gastro_join_perc_copy.apply(lambda x: shade_color(base_colors[x['most_prevalent_perc']], x['check_perc']), axis=1)

# Plotting
fig, ax = plt.subplots(1, 1, figsize=(10, 10))

# Plot each category with its specific color and without edges
for category in base_colors.keys():
    subset = gastro_join_perc_copy[gastro_join_perc_copy['most_prevalent_perc'] == category]
    subset.plot(ax=ax, color=subset['color_perc'], edgecolor=None)

# Add legend with custom labels for polygons
legend_patches = [mpatches.Patch(color=shade_color(base_colors[category], 0.7), label=legend_labels[category]) for category in base_colors.keys()]
ax.legend(handles=legend_patches)

# Overlay the points on the same ax
msize = 9
restaurants.plot(color='#636EFA', label=f'Restauracje ({restaurants.shape[0]})', markersize=msize, ax=ax, edgecolor="black", linewidth=0.5)
bars.plot(color='#EF553B', label=f'Bary ({bars.shape[0]})', markersize=msize, ax=ax, edgecolor="black", linewidth=0.5)
pubs.plot(color='#00CC96', label=f'Puby ({pubs.shape[0]})', markersize=msize, ax=ax, edgecolor="black", linewidth=0.5)

# Add a title
ax.set_title("Dominujący rodzaj gastro (%)")

plt.show()
No description has been provided for this image

Tresholds (?)¶

In [ ]:
# Extract the grid cells within given travel time threshold
threshold = 45
access = travel_time_df.loc[travel_time_df["travel_time_TRANSIT"] <= threshold].copy()
In [ ]:
print(access.shape)
access.head(3)
(2132, 12)
Out[ ]:
id zaludnienie geometry from_id_x to_id_x travel_time_TRANSIT from_id_y to_id_y travel_time_BIKE difference to_id tt_to_closest_library
1566 1566 8426 POLYGON ((21.04985 52.29419, 21.04975 52.29195... 0 1566 44.0 0 1566 62.0 -18.0 1566 13.0
1594 1594 6152 POLYGON ((20.92943 52.29398, 20.92933 52.29174... 0 1594 44.0 0 1594 58.0 -14.0 1594 15.0
1626 1626 9623 POLYGON ((21.04610 52.29201, 21.04600 52.28978... 0 1626 45.0 0 1626 61.0 -16.0 1626 8.0
In [ ]:
ax = access.plot(column="zaludnienie", figsize=(10,5), legend=True)
ax.set_title(f"The number of people living within {threshold} minutes travel time threshold.");
No description has been provided for this image
In [ ]:
pop_within_threshold = access["zaludnienie"].sum()
pop_share = pop_within_threshold / travel_time_df["zaludnienie"].sum()
print(f"Population within accessibility thresholds: {pop_within_threshold} ({pop_share*100:.0f} %)")
Population within accessibility thresholds: 15594779 (52 %)
In [ ]:
threshold = 15
# Count the number of opportunities from each grid cell
opportunities = travel_time_matrix.loc[travel_time_matrix["travel_time"]<=threshold].groupby("to_id")["from_id"].count().reset_index()

# Rename the column for more intuitive one
opportunities = opportunities.rename(columns={"from_id": "num_opportunities"})
In [ ]:
# Merge with population grid
opportunities = pop_grid.merge(opportunities, left_on="id", right_on="to_id")
In [ ]:
opportunities.head(3)
Out[ ]:
id zaludnienie geometry to_id num_opportunities
0 134 627 POLYGON ((20.93956 52.35875, 20.93946 52.35651... 134 1
1 180 1328 POLYGON ((20.93946 52.35651, 20.93936 52.35427... 180 2
2 227 1903 POLYGON ((20.93571 52.35433, 20.93561 52.35210... 227 1
In [ ]:
fig, ax = plt.subplots(figsize=(9, 9))
opportunities.plot(column="num_opportunities", scheme="natural_breaks", k=12, legend=True, ax=ax)
ax.set_title(f"Number of opportunities within {threshold} minutes.");
plt.show()
No description has been provided for this image
In [ ]: